package com.kpl.kplstzble.activity;

import static android.bluetooth.BluetoothGatt.GATT_SUCCESS;
import static com.kpl.kplstzble.fragment.UpgradationFragment.write;

import android.Manifest;

import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentTransaction;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;

import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Looper;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import com.kpl.kplstzble.R;
import com.kpl.kplstzble.fragment.HomeFragment;
import com.kpl.kplstzble.fragment.MeasureFragment;
import com.kpl.kplstzble.fragment.UpgradationFragment;
import com.kpl.kplstzble.utils.BleConstant;
import com.kpl.kplstzble.utils.BleHelper;
import com.kpl.kplstzble.utils.ByteUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

public class HomeActivity extends FragmentActivity implements  TextToSpeech.OnInitListener{
    private static final String TAG = HomeActivity.class.getSimpleName();
    public static BluetoothDevice bleDevice=null;
    public  static final String characteristicserviceuuid="00004b50-0000-1000-8000-00805f9b34fb";
    public  static final String characteristicuuid="0000ffe1-0000-1000-8000-00805f9b34fb";

    //public  static final String characteristicserviceuuid="0000fff0-0000-1000-8000-00805f9b34fb";
    //public  static final String characteristicuuid="0000fff1-0000-1000-8000-00805f9b34fb";
    /**
     * Gatt
     */
    public static BluetoothGatt bluetoothGatt;
    public static Context context;

    //加载框
    private ProgressDialog progressDialog;
    //private Button btnn;


    /**
     * 定位需要的权限
     */
    private String[] permissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION
            , Manifest.permission.ACCESS_COARSE_LOCATION
            , Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS
            , Manifest.permission.READ_EXTERNAL_STORAGE
            , Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private static final int OPEN_SET_REQUEST_CODE = 100;
    //语音播报
    public static TextToSpeech textToSpeech; // TTS对象

    public static String lastfolder;
    public static String lastfile;

    //文件路径前缀
    public static String propath;

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home);
        context=this;
        propath = getSavePath();
        //停止测亩
        MeasureFragment.workstatus=1;
        progressDialog = new ProgressDialog(this);
        progressDialog.show();

        //初始化
        // bleCallback = new BleCallback();
        //获取上个页面传递过来的设备
        bleDevice = getIntent().getParcelableExtra("device");
        String name = bleDevice.getName();
        //连接gatt 设置Gatt回调
        bluetoothGatt = bleDevice.connectGatt(this, false, bluetoothGattCallback);

        //btnn= (Button)findViewById(R.id.btnn);
        //先进行权限申请情况判断，没有权限申请权限
        if (lacksPermission(permissions)) {
            ActivityCompat.requestPermissions(this, permissions, OPEN_SET_REQUEST_CODE);
        } else {
            Log.i("LoginActivity", "");
        }
        textToSpeech = new TextToSpeech(this, this); // 参数Context,TextToSpeech.OnInitListener
        // 初始化并设置当前Fragment
        initFragment();
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
    /**
     * 权限申请回调，可以作进一步处理
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        // 此处为android 6.0以上动态授权的回调，用户自行实现。
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
    //判断是否获取权限
    public boolean lacksPermission(String[] permissions) {
        for (String permission : permissions) {
            //判断是否缺少权限，true=缺少权限
            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                return true;
            }
        }
        return false;
    }
    private void initFragment() {
        // 开启事务
       /* FragmentTransaction transaction = this.getSupportFragmentManager().beginTransaction();
        HomeFragment homeFragment = new HomeFragment();
        transaction.replace(R.id.fl_content,homeFragment).addToBackStack(null).commit();*/

        FragmentTransaction transaction = this.getSupportFragmentManager().beginTransaction();
        UpgradationFragment upgradationFragment = new UpgradationFragment();
        transaction.replace(R.id.fl_content,upgradationFragment).addToBackStack(null).commit();

    }

    @Override
    protected void onStop() {
        super.onStop();
    }
    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            int result = textToSpeech.setLanguage(Locale.CHINA);
            if (result == TextToSpeech.LANG_MISSING_DATA
                    || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Toast.makeText(this, "数据丢失或不支持", Toast.LENGTH_SHORT).show();
            }
        } else {
            Log.e("TTS", "Initilization Failed!");
        }
    }
    public static void read(String word){
        if (textToSpeech != null && !textToSpeech .isSpeaking()) {
            textToSpeech .setPitch(0.0f);// 设置音调，值越大声音越尖（女生），值越小则变成男声,1.0是常规
            textToSpeech .speak(word,
                    TextToSpeech.QUEUE_FLUSH, null);
        }
    }
    //蓝牙回调函数
    private final BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
        /**
         * 连接状态改变回调
         * @param gatt     gatt
         * @param status   gatt连接状态
         * @param newState 新状态
         */
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            Log.d(TAG, Thread.currentThread().getName());
            if (status == BluetoothGatt.GATT_SUCCESS) {
                progressDialog.dismiss();
                switch (newState) {
                    case BluetoothProfile.STATE_CONNECTED://连接成功
                        Log.d(TAG, "连接成功");
                        //获取MtuSize
                        gatt.requestMtu(512);
                        break;
                    case BluetoothProfile.STATE_DISCONNECTED://断开连接
                        Log.e(TAG, "断开连接");
                        Intent intent = new Intent(context, BlueToolthActivity.class);
                        startActivity(intent);
                        Toast.makeText(context, "蓝牙断开了", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
            } else {
                Intent intent = new Intent(context, BlueToolthActivity.class);
                startActivity(intent);
                Toast.makeText(context, "蓝牙断开了", Toast.LENGTH_SHORT).show();
                Log.e(TAG, "onConnectionStateChange: " + status);
            }
        }

        /**
         * 物理层改变回调
         * @param gatt   gatt
         * @param txPhy  发送速率  1M 2M
         * @param rxPhy  接收速率  1M 2M
         * @param status 更新操作的状态
         */
        @Override
        public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
            Log.d(TAG, "onPhyUpdate: txPhy: "+ txPhy + " rxPhy: "+ rxPhy);
        }

        /**
         * 读取物理层回调
         * @param gatt   gatt
         * @param txPhy  发送速率  1M 2M
         * @param rxPhy  接收速率  1M 2M
         * @param status 更新操作的状态
         */
        @Override
        public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
            Log.d(TAG, "onPhyRead: txPhy：" + txPhy + " rxPhy：" + rxPhy);
            if (txPhy == BluetoothDevice.PHY_LE_1M && rxPhy == BluetoothDevice.PHY_LE_1M){
                //获取2M的发送和接收速率
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    gatt.setPreferredPhy(BluetoothDevice.PHY_LE_2M, BluetoothDevice.PHY_LE_2M,
                            BluetoothDevice.PHY_OPTION_NO_PREFERRED);
                }
            }
        }

        /**
         * 发现服务回调
         * @param gatt   gatt
         * @param status gatt状态
         */
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            List<BluetoothGattService> services = gatt.getServices();
            services.forEach(service ->{
                System.out.println(service.getUuid());
                List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
                characteristics.forEach(characteristic ->{
                    System.out.println("    "+characteristic.getUuid());
                });
            });
            Log.d(TAG, "onServicesDiscovered");
            boolean notifyOpen = BleHelper.enableIndicateNotification(gatt);

            if (!notifyOpen) {
                Log.e(TAG, "开启通知属性异常");
                gatt.disconnect();
            }
        }

        /**
         * 特性读取回调
         * @param gatt           gatt
         * @param characteristic 特性
         * @param status         gatt状态
         */
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            Log.d(TAG, "onCharacteristicRead: characteristic: " + characteristic.getUuid().toString());
        }

        /**
         * 特性写入回调
         * @param gatt           gatt
         * @param characteristic 特性
         * @param status         gatt状态
         */
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            String command = ByteUtils.bytesToHexString(characteristic.getValue());
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.d(TAG, "onCharacteristicWrite: 写入成功：" + command);
            } else {
                Log.d(TAG, "onCharacteristicWrite: 写入失败：" + command);
            }
        }

        /**
         * 特性改变回调
         * @param gatt
         * @param characteristic 特性
         */
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            String strString = ByteUtils.bytesToHexString(characteristic.getValue());
            System.out.println("收到数据:" + strString);
            if(strString.startsWith("ff")){
                //忽略此数据
            }
            else if(strString.startsWith("fa")){//正常定位数据

                if(MeasureFragment.workstatus==0){
                    MeasureFragment.drawmap(strString);
                }

            }else if(strString.startsWith("41")){//强制改号

                System.out.println("强制改号成功");

            }else{//升级数据
                HashMap<String, String> result = UpgradationFragment.ParaseClientData(strString);
                if (result.get("type") != null) {
                    String type = result.get("type");//应答的帧的类型0x00：开始升级 0x01：文件信息 0x02：文件传输 0x03：传输结束
                    String rev = result.get("rev");//表示返回的结果 0x00：ACK FAIL 0x01：ACK OK
                    switch (type) {
                        case "00"://开始升级回复
                            if (!Objects.equals(rev, "00")) {//开始升级成功
                                System.out.println("一个升级文件分帧数2"+UpgradationFragment.filedatanum);
                                String hexfiledatanum = Integer.toHexString(UpgradationFragment.filedatanum);
                                System.out.println("一个升级文件分帧数hex"+hexfiledatanum);
                                int length = hexfiledatanum.length();
                                for (int i = 0; i < 6 - length; i++) {
                                    hexfiledatanum = "0" + hexfiledatanum;
                                }
                                String fileTypeHex = "0" + UpgradationFragment.fileType;
                                String data = "81C60501" +fileTypeHex  + hexfiledatanum;
                                String bcc = UpgradationFragment.yiHuo(data);

                                //发送文件信息
                                String senddata = "55" + data + bcc;
                                write(senddata);
                                UpgradationFragment.uploadlog.setText("收到 '开始升级指令' 回复成功！发送文件信息指令");
                            }
                            break;
                        case "01"://文件信息回复
                            if (Objects.equals(rev, "00")) {//文件信息回复失败
                                UpgradationFragment.revfilemesfailnum++;
                                UpgradationFragment.uploadlog.setText("收到 '文件信息' 回复失败！");
                                if (UpgradationFragment.revfilemesfailnum >= 3) {//超过三次失败处理
                                    UpgradationFragment.uploadlog.setText("收到 '文件信息' 回复失败三次！");
                                }
                            } else {
                                //第一次发送数据帧，循环序号置1
                                UpgradationFragment.circorder = 1;
                                UpgradationFragment.dataorder = 0;
                                UpgradationFragment.sendfiledata();
                                UpgradationFragment.uploadlog.setText("收到 '文件信息' 回复成功！发送文件传输指令");
                            }
                            break;
                        case "02"://文件数据传输回复
                            if (Objects.equals(rev, "00")) {//文件数据失败
                                UpgradationFragment.revfiledatafailnum++;
                                UpgradationFragment.uploadlog.setText("收到 '文件传输' 回复失败！第"+UpgradationFragment.circorder+"次循环："+"第"+UpgradationFragment.dataorder+"帧");
                                if (UpgradationFragment.revfiledatafailnum >= 3) {//超过三次失败处理
                                    UpgradationFragment.uploadlog.setText("收到 '文件传输' 回复失败三次！第"+UpgradationFragment.circorder+"次循环："+"第"+UpgradationFragment.dataorder+"帧");
                                } else {
                                    //失败不超过三次继续发送
                                    UpgradationFragment.sendfiledata();
                                }
                            } else {
                                UpgradationFragment.uploadlog.setText("文件传输中！");
                                if (((UpgradationFragment.circorder - 1) * 256 + UpgradationFragment.dataorder) == UpgradationFragment.filedatanum-1) {//判断是否是最后一帧数据+1，发送成功
                                    String data = "81C6020301";
                                    String bcc = UpgradationFragment.yiHuo(data);
                                    //发送文件信息
                                    String senddata = "55" + data + bcc;
                                    write(senddata);
                                } else {//最后一帧之前diaod
                                    if (((UpgradationFragment.circorder - 1) * 256 + UpgradationFragment.dataorder) == UpgradationFragment.filedatanum-2) {
                                        UpgradationFragment.dataorder++;
                                        //继续发送剩余数据
                                        UpgradationFragment.sendlastfiledata();
                                    }else {
                                        UpgradationFragment.dataorder++;
                                        //继续发送剩余数据
                                        UpgradationFragment.sendfiledata();
                                    }
                                }
                            }
                            break;
                        case "03"://传输结束回复
                            if (Objects.equals(rev, "00")) {//传输结束回复失败
                                UpgradationFragment.revoverfailnum++;
                                UpgradationFragment.uploadlog.setText("收到 '传输结束' 回复失败！");
                                if (UpgradationFragment.revoverfailnum >= 3) {//超过三次失败处理
                                    UpgradationFragment.uploadlog.setText("收到 '传输结束' 回复失败三次！");
                                }
                            } else {
                                //升级结束
                                Looper.prepare();
                                UpgradationFragment.circlePgBar.add(100);
                                UpgradationFragment.dataorder = 0;
                                UpgradationFragment.circorder = 0;
                                UpgradationFragment.uploadlog.setText("传输成功");
                                bluetoothGatt.disconnect();

                                Toast.makeText(context,"升级成功",Toast.LENGTH_LONG).show();
                                try {
                                    Thread.sleep(5000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                //跳转页面
                                Intent intent = new Intent(context, BlueToolthActivity.class);
                                startActivity(intent);
                                Looper.loop();

                                System.out.println("升级成功");
                            }
                            break;
                        default:
                            break;
                    }
                } else {
                    System.out.println("校验失败");
                 }
            }
        }
        //读取特性
        //Log.d(TAG, "onCharacteristicChanged: 读取特性 " + gatt.readCharacteristic(characteristic))
        /**
         * 描述符获取回调
         * @param gatt       gatt
         * @param descriptor 描述符
         * @param status     gatt状态
         */
        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            Log.d(TAG, "onDescriptorRead: descriptor: " + descriptor.getUuid().toString());
        }

        /**
         * 描述符写入回调
         * @param gatt       gatt
         * @param descriptor 描述符
         * @param status     gatt状态
         */
        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            if (BleConstant.DESCRIPTOR_UUID.equalsIgnoreCase(descriptor.getUuid().toString())) {
                if (status == GATT_SUCCESS) {
                    Log.d(TAG, "onDescriptorWrite: 通知开启成功");
                    //获取phy
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        gatt.readPhy();
                    }
                    //读取描述符
                    gatt.readDescriptor(descriptor);
                    //读取RSSI
                    gatt.readRemoteRssi();
                } else {
                    Log.d(TAG, "onDescriptorWrite: 通知开启失败");
                }
            }
        }

        /**
         * 可靠写入完成回调
         * @param gatt   gatt
         * @param status gatt状态
         */
        @Override
        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
            Log.d(TAG, "onReliableWriteCompleted: 可靠写入");
        }

        /**
         * 读取远程设备的信号强度回调
         * @param gatt   gatt
         * @param rssi   信号强度
         * @param status gatt状态
         */
        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            Log.d(TAG, "onReadRemoteRssi: rssi: " + rssi);
        }

        /**
         * Mtu改变回调
         * @param gatt   gatt
         * @param mtu    new MTU size
         * @param status gatt状态
         */
        @Override
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            Log.d(TAG, "onMtuChanged：mtu： " + mtu);
            //发现服务
            gatt.discoverServices();
        }
    };

    public static String getSavePath() {
        String path;
       // if (Build.VERSION.SDK_INT > 20) {
            path = context.getExternalFilesDir(null).getAbsolutePath();
       /* } else {
            path = Environment.getExternalStorageDirectory().getPath();
        }*/
        return path;
    }
}
